/**
 * Copyright (C) 2012-2013 jumei, Inc.
 * RpcBeanDefinitorParse.java
 * 2015年6月23日
 */
package com.goface.rpc.conf.parse;

import org.goface.rpc.invoker.SpringBeanInvoker;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.goface.rpc.conf.DefaultServiceConfigureCenter;
import com.goface.rpc.conf.ServiceConfigure;

/**
 * 
 * @author jm110
 */
public class RpcBeanDefinitorParse extends AbstractSingleBeanDefinitionParser {
	@Override
	protected Class<?> getBeanClass(Element element) {

		String classProperty = null;
		if (isClient(element)) {
			// 这里设置client bean 为ServiceConfigure，无实际意义，在BeanPostProcessor
			// 中会改写该类型
			classProperty = ServiceConfigure.class.getCanonicalName();
		} else {
			// server
			classProperty = element.getAttribute("class");
		}
		Class<?> clazz = null;
		try {
			clazz = Class.forName(classProperty);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
		return clazz;
	}

	private boolean isClient(Element element) {
		String beanType = element.getNodeName();
		return beanType.equals("rpc:client");
	}

	private ServiceConfigure parseServiceConfigure(Element element) {

		ServiceConfigure serviceConfigure = new ServiceConfigure();
		// 解析服务配置
		NamedNodeMap attributes = element.getAttributes();
		if (attributes == null) {
			throw new IllegalArgumentException(
					"there must be [interface],[ref] attributes in service client bean configure");
		}
		int len = attributes.getLength();
		for (int i = 0; i < len; ++i) {
			Node att = attributes.item(i);
			String name = att.getNodeName();
			String value = att.getNodeValue();
			serviceConfigure.addProperty(name, value);
		}
		// 子节点为service的属性参数配置
		NodeList children = element.getChildNodes();
		len = children.getLength();
		for (int i = 0; i < len; ++i) {
			Node node = children.item(i);
			String name = node.getNodeName();
			String value = node.getNodeValue();
			serviceConfigure.addProperty(name, value);
		}
		String beanType = element.getNodeName();
		serviceConfigure.addProperty(ServiceConfigure.SERVICE_TYPE, beanType);
		if (!serviceConfigure.isClientService()) {
			// spring bean service server TODO invoker 考虑是否用单实例
			serviceConfigure.addProperty(ServiceConfigure.SERVICE_INVOKER,
					new SpringBeanInvoker());
		}

		return serviceConfigure;
	}

	@Override
	protected void doParse(Element element, ParserContext parserContext,
			BeanDefinitionBuilder builder) {
		ServiceConfigure serviceConfigure = parseServiceConfigure(element);
		DefaultServiceConfigureCenter configureCenter = DefaultServiceConfigureCenter
				.getInstance();
		configureCenter.addServiceconfigure(serviceConfigure.getId(),
				serviceConfigure);
	}

}
